//! # Koda 沙箱管理器
//! 
//! 高性能、安全的沙箱管理系统，为Koda AI代码测试平台提供隔离的代码执行环境。
//! 
//! ## 核心功能
//! 
//! - **分层池化**: 冷池、温池、热池三层架构，实现毫秒级沙箱分配
//! - **智能调度**: 基于负载预测的资源调度算法
//! - **安全隔离**: 多层安全防护机制
//! - **性能监控**: 实时性能指标收集和异常检测
//! 
//! ## 使用示例
//! 
//! ```rust,no_run
//! use koda_sandbox_manager::{Manager, Config, SandboxSpec, Language};
//! 
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//!     let config = Config::default();
//!     let manager = Manager::new(config).await?;
//!     
//!     // 启动管理器
//!     manager.start().await?;
//!     
//!     // 创建沙箱规格
//!     let spec = SandboxSpec {
//!         language: Language::Python,
//!         ..Default::default()
//!     };
//!     
//!     println!("Manager started with spec: {:?}", spec);
//!     
//!     Ok(())
//! }
//! ```

use std::sync::Arc;

pub mod config;
pub mod error;
pub mod types;
pub mod logging;
pub mod retry;
pub mod sandbox_manager;
pub mod pool;
pub mod firecracker;
pub mod monitoring;
pub mod api;
pub mod grpc;
pub mod kafka;
pub mod scheduler;
pub mod load_balancer;

// 重新导出主要类型
pub use config::{Config, SandboxConfig};
pub use error::{Error, Result, ErrorContext};
pub use logging::{LoggingManager, LoggingDecorator, LogContext};
pub use retry::{RetryPolicy, RetryExecutor, RetryableOperations};
pub use types::*;
pub use sandbox_manager::{Sandbox, SandboxManager};

/// 沙箱管理器主结构
/// 
/// 提供沙箱的生命周期管理、资源池化、智能调度等核心功能
#[derive(Clone)]
pub struct Manager {
    /// 配置信息
    config: Arc<Config>,
    /// 沙箱管理器
    sandbox_manager: Arc<SandboxManager>,
    /// 日志管理器
    logging_manager: Arc<LoggingManager>,
}

impl LoggingDecorator for Manager {
    fn component_name(&self) -> &'static str {
        "koda_manager"
    }
}

impl Manager {
    /// 创建新的沙箱管理器实例
    /// 
    /// # 参数
    /// 
    /// * `config` - 配置信息
    /// 
    /// # 错误
    /// 
    /// 如果初始化失败，返回错误
    pub async fn new(config: Config) -> Result<Self> {
        // 创建日志管理器并初始化全局日志
        let logging_manager = Arc::new(LoggingManager::new(config.logging.clone()));
        logging_manager.init_global_logger()
            .context("Failed to initialize logging system")?;
        
        tracing::info!("Initializing Koda Sandbox Manager");
        
        let config = Arc::new(config);
        let sandbox_manager = Arc::new(
            SandboxManager::new(config.clone()).await
                .context("Failed to initialize sandbox manager")?
        );
        
        let manager = Self {
            config,
            sandbox_manager,
            logging_manager,
        };
        
        manager.log_info("Manager created successfully", Some(
            LogContext::new()
                .with_str("version", env!("CARGO_PKG_VERSION"))
                .with_str("environment", &manager.config.environment)
                .to_json()
        ));
        
        Ok(manager)
    }
    
    /// 启动管理器服务
    pub async fn start(&self) -> Result<()> {
        let start_time = std::time::Instant::now();
        
        self.log_info("Starting Koda Sandbox Manager", Some(
            LogContext::new()
                .with_str("config_env", &self.config.environment)
                .with_number("server_port", self.config.server.port as i64)
                .to_json()
        ));
        
        // 启动沙箱管理服务
        self.sandbox_manager.start().await
            .context("Failed to start sandbox manager")?;
        
        let duration = start_time.elapsed();
        self.log_info("Koda Sandbox Manager started successfully", Some(
            LogContext::new()
                .with_number("startup_duration_ms", duration.as_millis() as i64)
                .to_json()
        ));
        
        // 记录启动事件
        self.logging_manager.log_sandbox_event(
            "manager_started",
            "system",
            serde_json::json!({
                "startup_time_ms": duration.as_millis(),
                "config": {
                    "environment": self.config.environment,
                    "server_port": self.config.server.port,
                    "pool_sizes": {
                        "cold": self.config.pool.cold_pool_size,
                        "warm": self.config.pool.warm_pool_size,
                        "hot": self.config.pool.hot_pool_size
                    }
                }
            })
        );
        
        Ok(())
    }
    
    /// 停止管理器服务
    pub async fn stop(&self) -> Result<()> {
        let stop_time = std::time::Instant::now();
        
        self.log_info("Stopping Koda Sandbox Manager", None);
        
        // 停止沙箱管理服务
        if let Err(e) = self.sandbox_manager.stop().await {
            self.log_error(&e, Some(
                LogContext::new()
                    .with_str("operation", "sandbox_manager_stop")
                    .to_json()
            ));
            return Err(e).context("Failed to stop sandbox manager");
        }
        
        let duration = stop_time.elapsed();
        self.log_info("Koda Sandbox Manager stopped", Some(
            LogContext::new()
                .with_number("shutdown_duration_ms", duration.as_millis() as i64)
                .to_json()
        ));
        
        // 记录关闭事件
        self.logging_manager.log_sandbox_event(
            "manager_stopped",
            "system",
            serde_json::json!({
                "shutdown_time_ms": duration.as_millis()
            })
        );
        
        Ok(())
    }
    
    /// 获取沙箱管理器引用
    pub fn sandbox_manager(&self) -> Arc<SandboxManager> {
        self.sandbox_manager.clone()
    }
    
    /// 获取日志管理器引用
    pub fn logging_manager(&self) -> Arc<LoggingManager> {
        self.logging_manager.clone()
    }
    
    /// 获取配置引用
    pub fn config(&self) -> Arc<Config> {
        self.config.clone()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_manager_creation() {
        let config = Config::default();
        let manager = Manager::new(config).await;
        
        // 现在管理器创建应该成功
        assert!(manager.is_ok());
        
        let manager = manager.unwrap();
        assert!(manager.config().server.port > 0);
    }
}